-- Copyright (c) 2015,2016 Lucky Byte, Inc.
--
-- Summary : 多渠道终端交易判定模块
--
-- Author  : xiaohu <xiaohu@lucky-byte.com>
-- Since   : 2016.1.6
--
-- History
--  * 2016.01.06 吴小虎 : 创建此文件
--  * 2016.03.05 吴小虎 : 增加 _settl_needs
--

local _trcode_table = {
    -- msg_type + proc_code + cond_code + 48
    ['0100-930000-00-CI'] = { code = 'ttt', name = '建立定向委托关系' },
    ['0100-930000-00-XF'] = { code = 'ttt', name = '建立非定向委托关系' },
    ['0100-930000-00-KC'] = { code = 'ttt', name = '建立定向委托关系' },
    ['0100-930000-00-KX'] = { code = 'ttt', name = '建立非定向委托关系' },
    ['0100-940000-00-CI'] = { code = 'ttt', name = '撤销定向委托关系' },
    ['0100-940000-00-XF'] = { code = 'ttt', name = '撤销非定向委托关系' },
    ['0100-940000-00-KC'] = { code = 'ttt', name = '撤销定向委托关系' },
    ['0100-940000-00-KX'] = { code = 'ttt', name = '撤销非定向委托关系' },
    ['0100-990000-99-CD'] = { code = 'ttt', name = '取消所有委托关系' },
    ['0100-340000-00-CP'] = { code = 'ttt', name = '修改支付密码' },
    ['0100-340000-00-RS'] = { code = 'ttt', name = '重置支付密码' },
    ['0100-900000-00-CI'] = { code = 'ttt', name = '建立终端转账委托关系' },
    ['0100-910000-00-CI'] = { code = 'ttt', name = '撤销终端转账委托关系' },
    ['0100-920000-00-TD'] = { code = 'ttt', name = '建立终端定制关系' },
    ['0100-960000-00-TD'] = { code = 'ttt', name = '撤销终端定制关系' },
    ['0100-380000-00-CU'] = { code = 'ttt', name = '委托关系查询' },
    ['0100-380000-00-UC'] = { code = 'ttt', name = '委托关系查询' },
    ['0100-380000-00-KU'] = { code = 'ttt', name = '委托关系查询' },
    ['0100-380000-00-TN'] = { code = 'ttt', name = '委托关系查询' },
    ['0100-310000-92-FD'] = { code = 'ttt', name = '帐单费用查询' },
    ['0100-310000-92-KF'] = { code = 'ttt', name = '帐单费用查询' },
    ['0100-310000-87-IQ'] = { code = 'ttt', name = '行业信息查询' },
    ['0200-300000-00']    = { code = 'ttt', name = '银行卡余额查询' },
    ['0200-330000-00-CK'] = { code = 'ttt', name = '银行卡账户验证' },
    ['0200-330000-00-CB'] = { code = 'ttt', name = '银行卡账户验证' },
    ['0200-190000-81-PA'] = { code = 'ttt', name = '用户号码缴费(旧)' },
    ['0200-190000-81-LD'] = { code = 'ttt', name = '充值缴费(旧)' },
    ['0200-190000-81-CA'] = { code = 'ttt', name = '代收现金缴费(旧)' },
    ['0200-190000-81-KP'] = { code = 'ttt', name = '用户号码缴费' },
    ['0200-190000-81-KL'] = { code = 'ttt', name = '充值缴费' },
    ['0200-190000-81-KC'] = { code = 'ttt', name = '代收现金缴费' },
    ['0200-190000-81-XF'] = { code = 'ttt', name = '购买电子产品缴费' },
    ['0200-280000-81-PA'] = { code = 'ttt', name = '用户号码缴费撤销(旧)' },
    ['0200-280000-81-LD'] = { code = 'ttt', name = '充值缴费撤销(旧)' },
    ['0200-280000-81-CA'] = { code = 'ttt', name = '代收现金缴费撤销(旧)' },
    ['0200-280000-81-KP'] = { code = 'ttt', name = '用户号码缴费撤销' },
    ['0200-280000-81-KL'] = { code = 'ttt', name = '充值缴费撤销' },
    ['0200-280000-81-KC'] = { code = 'ttt', name = '代收现金缴费撤销' },
    ['0200-280000-81-XF'] = { code = 'ttt', name = '购买电子产品缴费撤销' },
    ['0200-190000-82-CN'] = { code = 't20', name = '消费',
        trctl = true, settl = true, hasfee = true,
        reversable = true, revokable = true
    },
    ['0200-280000-82-CN'] = { code = 'ttt', name = '消费撤销' },
    ['0200-190000-81-SC'] = { code = 'ttt', name = '单笔代收' },
    ['0200-280000-81-SC'] = { code = 'ttt', name = '单笔代收撤销' },
    ['0200-290000-00-DF'] = { code = 'ttt', name = '实时代付' },
    ['0200-010000-00']    = { code = 't60', name = '助农取款' },
    ['0200-400000-00']    = { code = 'ttt', name = '委托终端转账' },
    ['0200-480000-00-T3'] = { code = 'ttt', name = '卡卡转账' },
    ['0200-600000-91-QC'] = { code = 'ttt', name = '电子现金指定账户圈存' },
    ['0200-620000-91-QC'] = { code = 'ttt', name = '电子现金非指定账户圈存' },
    ['0200-630000-91']    = { code = 'ttt', name = '现金充值' },
    ['0200-170000-91']    = { code = 'ttt', name = '现金充值撤销' },
    ['0200-350000-00-PV'] = { code = 'ttt', name = '票据打印(旧)' },
    ['0200-350000-00-KV'] = { code = 'ttt', name = '票据打印' },

    -- msg_type + proc_code + cond_code
    ['0220-200000-82'] = { code = 'ttt', name = '消费退货' },
    ['0220-200000-00'] = { code = 'ttt', name = '退货' },
    ['0220-190000-82'] = { code = 'ttt', name = 'IC卡脱机消费交易上送' },
    ['0220-290000-68'] = { code = 'ttt', name = '代付确认' },

    -- msg_type + 60.3
    ['0320-203'] = { code = 'ttt', name = '基于PBOC借/贷记IC卡TC值上送' },
    ['0620-951'] = { code = 'ttt', name = '基于PBOC借/贷记标准IC卡脚本处理结果通知' },
    ['0800']     = { code = 't1', name = '终端签到',
        nomac = true
    },
    ['0800-001'] = { code = 't1', name = 'DES终端签到',
        nomac = true
    },
    ['0800-003'] = { code = 't1', name = '3DES终端签到',
        nomac = true
    },
    ['0800-370'] = { code = 'ttt', name = 'IC卡公钥下载' },
    ['0800-380'] = { code = 'ttt', name = 'IC卡参数下载' },
    ['0800-371'] = { code = 'ttt', name = 'IC卡公钥下载结束' },
    ['0800-381'] = { code = 'ttt', name = 'IC卡参数下载结束' },
    ['0820-372'] = { code = 'ttt', name = 'IC卡公钥下载' },
    ['0820-382'] = { code = 'ttt', name = 'IC卡参数下载' },
}

-- 通过报文字段内容获取其对应的交易名称
lib351.trinfo = function(packet)
    assert(packet._class == 'Packet351', string.format(
        'lib351.trinfo() 需要 Packet351 报文，当前报文类型为[%s]', packet._class))

    -- 不能匹配时的返回值
    local _default = {
        code = 'ttt', name = '未知交易'
    }

    local _msg_type = packet.msg_type()
    if not _msg_type then
        logger.warn('报文交易类型为空，无法获取对应的交易名称.')
        return _default
    end
    local _proc_code = packet.proc_code()
    local _cond_code = packet.cond_code()
    local _priv_data = packet.priv_data()

    if _msg_type == '0400' then -- 冲正交易
        if not _proc_code or not _cond_code or not _priv_data then
            logger.warn('冲正报文缺少必须的字段.')
            return {
                code = 't22', name = '冲正-原交易未知'
            }
        end
        local _pattern = string.format('%s-%s-%s', _proc_code, _cond_code,
                             string.upper(string.sub(_priv_data, 1, 2)))
        for k, v in _code_name_table do
            local _sub = string.sub(k, 6)
            if _sub == _pattern then
                return {
                    code = 't22', name = '冲正-' .. v
                }
            end
        end
        logger.warn('通过 ' .. _pattern .. ' 不能匹配冲正原交易.')
        return {
            code = 't22', name = '冲正-原交易未知'
        }
    end

    if _msg_type == '0320' or _msg_type == '0620' or
       _msg_type == '0800' or _msg_type == '0820' then
        local _resv = packet.reserved()
        if not _resv then
            logger.warn(_msg_type .. '类交易缺少60字段.')
            return _trcode_table[_msg_type] or _default
        end
        local _micode = string.sub(_resv, 9, 11)
        return _trcode_table[_msg_type .. '-' .. _micode] or _default
    end

    if _msg_type == '0220' then
        if not _proc_code or not _cond_code then
            logger.warn('0220 报文缺少必须的字段.')
            return _default
        end
        local _key = string.format('%s-%s-%s', _msg_type, _proc_code, _cond_code)
        return _trcode_table[_key] or _default
    end

    local _key = string.format('%s-%s-%s', _msg_type, _proc_code, _cond_code)
    if _priv_data then
        _key = _key .. '-' .. string.upper(string.sub(_priv_data, 1, 2))
    end
    return _trcode_table[_key] or _default
end
